package com.lucky.common.controller;

import com.lucky.common.enums.AppConst;
import com.lucky.common.pojo.bo.AttachFile;
import com.lucky.common.pojo.vo.UserVO;
import com.lucky.common.util.FileUtil;
import com.lucky.common.util.StringUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

@CrossOrigin(origins = "*", maxAge = 3600)
@RestController
@RequestMapping("/uploader")
public class UploadController {

	/**上传地址*/
    @Value("${lucky.file.upload-path}")
    private String filePath;
    
    @Value("${lucky.file.tmp-path}")
    private String appTempPath;

	private String EVENT_SUCCESS="success";
	private String EVENT_FAIL="fail";
    
    // 执行上传
    @PostMapping("/upload")
    public Result upload(MultipartHttpServletRequest request, Model model) {

		MultipartHttpServletRequest multipartRequest =  request;
//		List<MultipartFile> fileList = multipartRequest.getFiles("file");
		//List<MultipartFile> fileList = (List<MultipartFile>) multipartRequest.getAttribute("fileList");
		List<MultipartFile> fileList = multipartRequest.getFiles("fileList");

		Integer fileSizeMbLimit=10;
		if(request.getParameter("fileSizeMbLimit")!=null){
			fileSizeMbLimit=Integer.valueOf(request.getParameter("fileSizeMbLimit"));
		};

		String type = request.getParameter("type");
		UserVO user=null;


		Result<AttachFile> childResult;
		List<Result> childResultList=new ArrayList<Result>();



		for(MultipartFile file:fileList){
			childResult=upload(file,user,type,fileSizeMbLimit);
			childResultList.add(childResult);
		}

		Result result=new Result();
		result.setEvent(EVENT_SUCCESS);

		Integer failCount=0;

		for(Result item:childResultList){
			if(EVENT_FAIL.equals(item.getEvent())){
				failCount++;
			}
		}

		Result<List<Result>> r=new Result();
		r.setErrorCode("0");
		r.setEvent(EVENT_SUCCESS);
		r.setTips("上传成功");
		r.setVo(childResultList);

		if(failCount>0){
			r.setEvent(EVENT_FAIL);
			r.setTips("有 "+failCount+" 个文件上传不成功，请检查结果");
			r.setErrorCode("1");
		}

		return r;
    }

	/**
	 * 上传文件
	 * @param file
	 * @param user
	 * @param types
	 * @return
	 */
	public Result<AttachFile> upload(MultipartFile file,UserVO user,String types,Integer fileSizeMbLimit) {
		String fileName;
		Long fileSize;
		String ext;

		fileName=file.getOriginalFilename();
		fileSize=file.getSize();

		ext = fileName.substring(fileName.lastIndexOf(".")).toLowerCase();

		AttachFile vo=new AttachFile();
		vo.setFileName(fileName);
		vo.setFileSize(fileSize);

		Result result=new Result();
		result.setEvent(EVENT_SUCCESS);
		result.setTips("上传成功");
		result.setVo(vo);

		//页面允许的扩展名验证
		if(types!=null && !"".equals(types)){
			Result extResult=validateExt(ext,types);
			if(extResult.getEvent().equals(EVENT_FAIL)){
				result.setEvent(EVENT_FAIL);
				result.setTips(extResult.getTips());
				return result;
			}
		}
		//系统允许的扩展名验证
		if (!AppConst.ATTACH_TYPE.contains(ext)) {
			result.setEvent(EVENT_FAIL);
			result.setTips("请上传jpg、jpeg、png、pdf、rar、zip、xls格式的附件！");
			return result;
		}

		if (fileName.substring(0, fileName.lastIndexOf(".")).length() > 60) {
			result.setEvent(EVENT_FAIL);
			result.setTips("附件名字最多60个字符！");
			return result;
		}
		if (fileSize> 1024*1024*fileSizeMbLimit) {
			result.setEvent(EVENT_FAIL);
			result.setTips("上传失败！上传附件大小超过 "+fileSizeMbLimit+" MB！");
			return result;
		}

		if (EVENT_SUCCESS.equals(result.getEvent())) {
			SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmssSSS");
			Date d = new Date();
			String save_name = "";
			if (null == user) {
				save_name = df.format(d) + "_" + new Random().nextInt(1000000) + "_" + "regUserName" + ext;
			} else {
				save_name = df.format(d) + "_" + new Random().nextInt(1000000) + "_" + user.getUserName() + ext;
			}
			String tempPath = FileUtil.getRootPath(appTempPath);
			String dateStr = StringUtil.dateToString(new Date(), "yyyy/MM/dd");// 子目录年月路径

			File dir = new File(tempPath + dateStr);
			if (!dir.exists() || !dir.isDirectory()){
				dir.mkdirs();// 目录不存在 创建
			}
			FileOutputStream outputStream = null;
			try {
				outputStream = new FileOutputStream(new File(tempPath+ dateStr + "/" + save_name));
				outputStream.write(file.getBytes());
				outputStream.close();
				outputStream=null;

				result.setEvent(EVENT_SUCCESS);
				result.setErrorCode("0");
				result.setTips("上传成功");
				String serverFileName=dateStr + "/" + save_name;
				vo.setServerFileName(serverFileName);
				return result;
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();

				result.setEvent(EVENT_FAIL);
				result.setTips("上传失败");
				return result;
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();

				result.setEvent(EVENT_FAIL);
				result.setTips("上传失败");
				return result;
			}finally {
				if (outputStream != null) {
					try {
						outputStream.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		}
		result.setEvent(EVENT_FAIL);
		result.setTips("未知错误");
		return result;
	}

	/**
	 * 验证文件扩展名
	 * @param ext
	 * @param allowExts
	 * @return
	 */
	private Result validateExt(String ext,String allowExts){
		ext=ext.toLowerCase();
		allowExts=allowExts.toLowerCase();
		String[] allowExtArray=allowExts.split(";");
		StringBuffer sb=new StringBuffer();
		ext=ext.replace(".","");

		for(int i=0;i<allowExtArray.length;i++){
			allowExtArray[i]=allowExtArray[i].replace("*.", "");
			sb.append("、");
			sb.append(allowExtArray[i]);
		}
		if(sb.length()>0){
			sb.deleteCharAt(0);
		}

		Result result=new Result();
		result.setEvent(EVENT_FAIL);
		result.setTips("请上传"+sb.toString()+"格式的附件！");

		for(int i=0;i<allowExtArray.length;i++){
			if(ext.equals(allowExtArray[i])){
				result.setEvent(EVENT_SUCCESS);
				result.setTips("通过");
				break;
			}
		}
		return result;
	}

	public class Result<T> {
		private String event;
		private String errorCode;
		private String tips;
		private T vo;

		public String getEvent() {
			return event;
		}

		public void setEvent(String event) {
			this.event = event;
		}

		public String getErrorCode() {
			return errorCode;
		}

		public void setErrorCode(String errorCode) {
			this.errorCode = errorCode;
		}

		public String getTips() {
			return tips;
		}

		public void setTips(String tips) {
			this.tips = tips;
		}

		public T getVo() {
			return vo;
		}

		public void setVo(T vo) {
			this.vo = vo;
		}
	}
}
